package mq

import (
	"context"
	"errors"
	"task_queue/internal/models"
)

// MQType 为了兼容性保留类型别名
type MQType = models.MQType

// 使用 models 包中定义的常量
const (
	RabbitMQ     = models.RabbitMQ
	Kafka        = models.Kafka
	NSQ          = models.NSQ
	RocketMQ     = models.RocketMQ
	Redis        = models.Redis
	ChannelQueue = models.ChannelQueue
)

// ErrUnsupportedMQType 表示不支持的消息队列类型
var ErrUnsupportedMQType = errors.New("不支持的消息队列类型")

// MQStatus 表示消息队列的状态信息
type MQStatus struct {
	IsConnected    bool   `json:"is_connected"`    // 是否已连接
	ConnectionInfo string `json:"connection_info"` // 连接信息
	StartTime      int64  `json:"start_time"`      // 启动时间戳
	ErrorCount     int    `json:"error_count"`     // 错误计数
	LastError      string `json:"last_error"`      // 最后一次错误信息
}

// QueueStats 表示队列的统计信息
type QueueStats struct {
	TopicName        string `json:"topic_name"`        // 主题名称
	PendingMessages  int64  `json:"pending_messages"`  // 待处理消息数
	ConsumedMessages int64  `json:"consumed_messages"` // 已消费消息数
	FailedMessages   int64  `json:"failed_messages"`   // 处理失败的消息数
	LastConsumedAt   int64  `json:"last_consumed_at"`  // 最后消费时间戳
}

// MessageRecord 表示消息记录
type MessageRecord struct {
	Message   string `json:"message"`         // 消息内容
	Timestamp int64  `json:"timestamp"`       // 时间戳
	Error     string `json:"error,omitempty"` // 错误信息（如果有）
}

// Producer 生产者接口
type Producer interface {
	// Publish 发布字符串消息到指定主题
	Publish(ctx context.Context, topic string, message string) error
	// Close 关闭生产者连接
	Close() error
}

// Consumer 消费者接口
type Consumer interface {
	// Subscribe 订阅指定主题的消息
	Subscribe(ctx context.Context, topic string, handler func(message string) error) error
	// Close 关闭消费者连接
	Close() error
}

// StatusProvider 状态提供者接口
type StatusProvider interface {
	// GetStatus 获取消息队列的状态
	GetStatus() MQStatus
	// GetQueueStats 获取指定主题的队列统计信息
	GetQueueStats(topic string) (QueueStats, error)
	// ListQueueStats 获取所有主题的队列统计信息
	ListQueueStats() []QueueStats
	// GetPendingMessages 获取待处理的消息
	GetPendingMessages(topic string, page, pageSize int) ([]string, error)
	// GetConsumedMessages 获取已消费的消息
	GetConsumedMessages(topic string, page, pageSize int) ([]MessageRecord, error)
	// GetFailedMessages 获取失败的消息
	GetFailedMessages(topic string, page, pageSize int) ([]MessageRecord, error)
	// CloseQueue 关闭指定主题的队列
	CloseQueue(topic string) error
	// ListTopics 获取所有主题列表
	ListTopics() []string
}

// MQPlugin 消息队列插件接口，同时实现生产者、消费者和状态提供者功能
type MQPlugin interface {
	Producer
	Consumer
	StatusProvider
	Type() MQType
}

// NewMQPlugin 创建指定类型的消息队列插件实例
func NewMQPlugin(mqType MQType, config map[string]interface{}) (MQPlugin, error) {
	switch mqType {
	case RabbitMQ:
		return newRabbitMQPlugin(config)
	case Kafka:
		return newKafkaPlugin(config)
	case NSQ:
		return newNSQPlugin(config)
	case RocketMQ:
		return newRocketMQPlugin(config)
	case Redis:
		return newRedisPlugin(config)
	case ChannelQueue:
		return newChannelQueuePlugin(config)
	default:
		return nil, ErrUnsupportedMQType
	}
}
